/*
 * Copyright © 2004-2014 chenYuan. All rights reserved.
 * @Website:wwww.jspx.net
 * @Mail:39793751@qq.com
 * @author: chenYuan , 陈原
 * @License: Jspx.net Framework Code is open source (LGPL)，Jspx.net Framework 使用LGPL 开源授权协议发布。
 * @jvm:jdk1.6+  x86/amd64
 *
 */
package com.jspx.txweb.config;

import com.jspx.boot.EnvFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jspx.boot.environment.EnvironmentTemplate;
import com.jspx.boot.environment.Environment;
import com.jspx.io.AbstractRead;
import com.jspx.io.AutoReadTextFile;
import com.jspx.utils.ArrayUtil;
import com.jspx.utils.FileUtil;
import com.jspx.utils.StringUtil;
import com.jspx.utils.XMLUtil;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.io.File;

/**
 * Created by IntelliJ IDEA.
 * User:chenYuan (mail:39793751@qq.com)
 * Date: 2007-1-5
 * Time: 15:02:05
 */
public class DefaultConfiguration implements Configuration {
    final static private Logger log = LoggerFactory.getLogger(DefaultConfiguration.class);

    //包含的文件,用作判断，如果已经载入的文件将不再载入
    static private String[] includeFiles = null;
    //默认载入的文件名
    private String fileName = "jspx.txweb.xml";

    //默认环境
    private EnvironmentTemplate envTemplate = EnvFactory.getEnvironmentTemplate();
    private Map<String, String> extendMap = new Hashtable<String, String>();
    //每个命名空间里边的默认拦截器列表
    private Map<String, List<DefaultInterceptorBean>> defaultInterceptorMap = new Hashtable<String, List<DefaultInterceptorBean>>();
    private Map<String, List<DefaultUrlInterceptorBean>> defaultUrlInterceptorMap = new Hashtable<String, List<DefaultUrlInterceptorBean>>();
    private Map<String, List<ResultConfigBean>> defaultResultMap = new HashMap<String, List<ResultConfigBean>>();

    private static Configuration instance =  new DefaultConfiguration();
    public static Configuration getInstance() {
        return instance;
    }
    private DefaultConfiguration() {

    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public Map<String, List<DefaultInterceptorBean>> getDefaultInterceptorMap() {
        return defaultInterceptorMap;
    }

    public Map<String, List<DefaultUrlInterceptorBean>> getDefaultUrlInterceptorMap() {
        return defaultUrlInterceptorMap;
    }

    public Map<String, String> getExtendMap() {
        return extendMap;
    }

    public Map<String, List<ResultConfigBean>> getDefaultResultMap() {
        return defaultResultMap;
    }

    public Map<String, Map<String, ActionConfigBean>> loadConfigMap() throws Exception {

        final Map<String, Map<String, ActionConfigBean>> actionConfigMap = new Hashtable<String, Map<String, ActionConfigBean>>();
        if (!StringUtil.isNULL(envTemplate.getString(Environment.TXWebConfig))) {
            fileName = envTemplate.getString(Environment.TXWebConfig);
        }
        String defaultFile = fileName;
        if (!FileUtil.isFileExist(defaultFile)) {
            String temp = envTemplate.getString(Environment.defaultPath);
            if (StringUtil.isNULL(temp)) {
                temp = StringUtil.empty;
            }
            defaultFile = temp + fileName;
        }

        if (!FileUtil.isFileExist(defaultFile)) {
            URL url = Environment.class.getResource("/" + fileName);
            if (url != null) {
                defaultFile = url.getPath();
            }
        }

        if (!FileUtil.isFileExist(defaultFile)) {
            URL url = Environment.class.getResource(fileName);
            if (url != null) {
                defaultFile = url.getPath();
            }
        }

        if (!FileUtil.isFileExist(defaultFile)) {
            throw new Exception("not find TXWeb config file:" + defaultFile);
        }

        fileName = defaultFile;

        String defaultPath = FileUtil.getParentPath(fileName);
        if (StringUtil.isNULL(defaultPath)) defaultPath = envTemplate.getString(Environment.defaultPath);
        String[] includeFixedFiles = new String[1];
        includeFixedFiles[0] = fileName;
        readIncludeFile(defaultPath, includeFixedFiles, actionConfigMap);
        includeFiles = null;
        return actionConfigMap;
    }

    /**
     * @param defaultPath     默认路径
     * @param include         包含的路径
     * @param actionConfigMap 全局配置列表
     * @throws Exception 异常
     */
    private void readIncludeFile(String defaultPath, final String[] include, Map<String, Map<String, ActionConfigBean>> actionConfigMap) throws Exception {
        if (include == null) return;

        for (String file : include) {
            if (StringUtil.isNULL(file)) continue;

            String defaultFile;
            if (FileUtil.isFileExist(file)) defaultFile = file;
            else defaultFile = FileUtil.mendFile(defaultPath + file);

            if (!FileUtil.isFileExist(defaultFile)) {
                URL url = Environment.class.getResource("/" + file);
                if (url != null) {
                    defaultFile = url.getPath();
                }
            }
            if (!FileUtil.isFileExist(defaultFile)) {
                URL url = Environment.class.getResource(file);
                if (url != null) {
                    defaultFile = url.getPath();
                }
            }
            if (!FileUtil.isFileExist(defaultFile)) continue;

            File readFile = new File(defaultFile);
            if (ArrayUtil.inArray(includeFiles, readFile.getAbsolutePath(), true)) continue;
            includeFiles = ArrayUtil.add(includeFiles, readFile.getAbsolutePath());

            if (log.isDebugEnabled()) log.debug("TXWeb load config file:" + file);

            AbstractRead ar = new AutoReadTextFile();
            ar.setEncode(envTemplate.getString(Environment.encode,Environment.defaultEncode));
            ar.setFile(readFile);
            ReadConfig readConfig = new ReadConfig(actionConfigMap, extendMap, defaultInterceptorMap, defaultUrlInterceptorMap, defaultResultMap);
            if (XMLUtil.parseXmlString(readConfig,ar.getContent()))
            {
                String[] includeFixedFiles = null;
                String[] iFiles = readConfig.getInclude();
                if (iFiles != null)
                    for (String mif : iFiles) {
                        if (FileUtil.isPatternFileName(mif)) {
                            File[] fileName = FileUtil.getPatternFiles(defaultPath, mif);
                            for (File f : fileName) {
                                includeFixedFiles = ArrayUtil.add(includeFixedFiles, f.getName());
                            }
                        } else includeFixedFiles = ArrayUtil.add(includeFixedFiles, mif);
                    }
                readIncludeFile(defaultPath, includeFixedFiles, actionConfigMap);
            } else {
                log.error("TXWeb load config file xml error:" + file);
            }
        }
    }
}